package com.bestcem.xm.survey.export;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.survey.grpc.client.dto.QstructsDto;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author xiaoshu.shao
 * @date 2023/3/7 11:40
 */
public interface BaseTypeHandler {

    default Map<String, String> getSelectColumnChangeDictV2(JSONObject data, String dtype) {
        return Collections.emptyMap();
    }

    /**
     * 清除html标签,中间换行转空格,两端换行去掉
     *
     * @param title
     * @return
     */
    static String clearHtml(String title) {
        return stripHtmlWarp(title);
    }

    /**
     * 清除html标签,中间换行转空格,两端换行去掉
     *
     * @param title
     * @return
     */
    static String stripHtmlWarp(String title) {
        if (Objects.nonNull(title)) {
            return HtmlUtil.cleanHtmlTag(title);
        }
        return "";
    }

    default Map<String, String> getOpenColumnChangeDictV2(JSONObject data) {
        return Collections.emptyMap();
    }

    default boolean isOpenRow(JSONObject v) {
        return (boolean) v.getOrDefault("is_open", false);
    }

    default boolean isOpenOption(JSONObject item) {
        return (boolean) item.getOrDefault("is_open", false);
    }

    default Map<String, String> getScoreColumnChangeDictV2(JSONObject data, QstructsDto qStruct) {
        return Collections.emptyMap();
    }

    /**
     * 获取第一行表头-题目
     *
     * @param data
     * @param dtype
     * @return
     */
    default List<String> getSelectColumnListV2(JSONObject data, String dtype) {
        return Collections.emptyList();
    }

    /**
     * 获取第一行表头数据
     *
     * @param data
     * @return
     */
    default List<String> getOpenColumnListV2(JSONObject data) {
        return Collections.emptyList();
    }

    default List<String> getScoreColumnListV2(JSONObject data, QstructsDto qStruct) {
        return Collections.emptyList();
    }

    default Map<String, Map<Object, Object>> getConvertTableV2(JSONObject q) {
        return Collections.emptyMap();
    }

    /**
     * 获取题目数据
     *
     * @param data
     * @param answers
     * @param dtype
     * @param score_apply_type
     * @return
     */
    default Map<Object, Object> getSelectAnswerDictV2(JSONObject data, Object answers, String dtype, Boolean score_apply_type) {
        return Collections.emptyMap();
    }

    /**
     * 填空项答案字典
     *
     * @param answers
     * @param answers
     * @return
     */
    default Map<Object, Object> getOpenReadableDictV2(JSONObject data, Object answers) {
        return getOpenAnswerDictV2(data, answers);
    }

    /**
     * 填空项答案字典
     *
     * @param answers
     * @return
     */
    default Map<Object, Object> getOpenAnswerDictV2(JSONObject data, Object answers) {
        return Collections.emptyMap();
    }

    default Map<Object, Object> getScoreReadableDictV2(JSONObject data, Object answers, QstructsDto qstructsDto, JSONObject score_dict, String dtype) {
        return getScoreAnswerDictV2(data, answers, qstructsDto, score_dict, dtype);
    }

    default Map<Object, Object> getScoreAnswerDictV2(JSONObject data, Object answers, QstructsDto qstructsDto, JSONObject score_dict, String dtype) {
        return Collections.emptyMap();
    }

    static boolean checkAnswerAllRight(String qgid, JSONObject gid_score_dict, Object ans, String qtype) {
        List<Boolean> all_lt_zero = new ArrayList<>();
        for (String i : gid_score_dict.keySet()) {
            if (i.startsWith(qgid) && !"".equals(gid_score_dict.getString(i))) {
                if (Float.parseFloat(gid_score_dict.getString(i)) < 0) {
                    all_lt_zero.add(Boolean.TRUE);
                } else {
                    all_lt_zero.add(Boolean.FALSE);
                }
            } else {
                all_lt_zero.add(Boolean.FALSE);
            }
        }
        int size = all_lt_zero.size();
        Boolean[] all = all_lt_zero.toArray(new Boolean[size]);
        if (all.length > 0 && BooleanUtil.andOfWrap(all)) {
            return false;
        }

        List<String> all_score_gte_zero_gids = new ArrayList<>();
        List<String> answers_gids = new ArrayList<>();
        if ("matrix_multiple".equals(qtype)) {
            gid_score_dict.forEach((k, v) -> {
                if (qgid.equals(k.split("_")[0]) && !"".equals(v.toString()) && Float.parseFloat((String) v) > 0) {
                    all_score_gte_zero_gids.add(k);
                }
            });
            ((JSONObject) ans).forEach((k, v) -> {
                JSONArray sonarry = (JSONArray) v;
                sonarry.forEach(j -> {
                    String ret = String.format("%s_%s_%s", qgid, k, ((JSONArray) j).get(0));
                    answers_gids.add(ret);
                });
            });
        } else if ("multiple".equals(qtype)) {
            gid_score_dict.forEach((k, v) -> {
                if (qgid.equals(k.split("_")[0]) && !"".equals(v.toString()) && Float.parseFloat((String) v) > 0) {
                    all_score_gte_zero_gids.add(k);
                }
            });
            ((List) ans).forEach(i -> answers_gids.add(String.format("%s_%s", qgid, i)));
        }
        boolean flag = false;
        if (all_score_gte_zero_gids.isEmpty() || answers_gids.isEmpty() || all_score_gte_zero_gids.size() != answers_gids.size()) {
            flag = true;
        }
        //若答案gid 和 配置的全对gid 有差异 则次题答案非全对
        List<Boolean> all_right = new ArrayList<>();
        answers_gids.forEach(v -> all_right.add(all_score_gte_zero_gids.contains(v)));
        if (CollUtil.isEmpty(answers_gids)) {
            flag = true;
        }
        //若答案gid 和 配置的全对gid 有差异 则此题答案非全对
        if (CollUtil.isEmpty(all_right) || all_right.stream().allMatch(Boolean::valueOf)) {
            return true;
        }
        return flag;
    }

    default List<List<String>> getVarLabelsV2(JSONObject dataValue, boolean not01, boolean need_title) {

        return Collections.emptyList();
    }

    default String getTitles(JSONObject data, JSONObject row, JSONObject item, boolean not_need_title) {
        String s = not_need_title ? "" : getUnquotedStr(data.getString("title"), false);
        if (CollUtil.isNotEmpty(row)) {
            String row_title = getUnquotedStr(data.getString("title"), false);
            if (StrUtil.isNotEmpty(row_title)) {
                s += ":" + row_title;
            }
        }
        if (CollUtil.isNotEmpty(item)) {
            String item_title = getUnquotedStr(data.getString("title"), true);
            if (StrUtil.isNotEmpty(item_title)) {
                s = not_need_title ? item_title : ":" + item_title;
            }
        }
        return s;
    }

    default String getUnquotedStr(String text, boolean not01) {
        if (not01) {
            return clearHtml(text).replaceAll("'", "").replaceAll("\"", "");
        }
        return text.replaceAll("'", "").replaceAll("\"", "");
    }

    static List<String> convertString(String s, int length) {
        Pattern rWords = Pattern.compile("\\b([ \\w]{0," + (length - 1) + "}\\w)\\b");
        Matcher matcher = rWords.matcher(s);
        List<String> data = new ArrayList<>();
        while (matcher.find()) {
            data.add(matcher.group());
        }
        return data;
    }

    default void getValItemsV2(JSONObject dataValue, List head_list, List val_list, boolean not01, boolean not_need_title) {
        String s = String.format("ADD VALUE LABELS %s", StrUtil.join(" ", head_list));
        List<String> data_list = convertString(s, 250);
        val_list.addAll(data_list);
        if (not01) {
            List<JSONObject> items = (List<JSONObject>) dataValue.getOrDefault("items", Collections.emptyList());
            for (int i = 0; i < items.size(); i++) {
                JSONObject item = items.get(i);
                if (not01) {
                    val_list.add(not_need_title ? String.format("    %s '%s'%s", item.get("oid"), getUnquotedStr(item.getString("title"), true), i + 1 == items.size() ? "" : ".") :
                            String.format("    %s '%s:%s'%s", item.get("oid"), getUnquotedStr(dataValue.getString("title"), true), getUnquotedStr(item.getString("title"), true), i + 1 == items.size() ? "" : "."));
                }
            }
        } else {
            val_list.add("    0 '否'");
            val_list.add("    1 '是'.");
        }
    }

    default List<String> getSpssCodeV2(JSONObject param, QstructsDto qstruct) {
        return Collections.emptyList();
    }

    /**
     * 获取所属的答题类型
     *
     * @return
     */
    String getQuestionTypeValue();


    default List<Map<String, Object>> getExtraAnswerDictListV2(JSONObject dataValue, List<Map<String, List<String>>> answers, boolean readablecol) {
        return Collections.emptyList();
    }

    default List<JSONObject> getSortedTagList(JSONObject data) {
        List<JSONObject> tag_list = (List<JSONObject>) ((Map) data.getJSONObject("current_template").getOrDefault("tagList", Collections.emptyMap())).values().stream().collect(Collectors.toList());
        tag_list.sort((a, b) -> {
            String[] a1 = ((List<String>) a.get("ooid")).get(0).split("_");
            String[] b1 = ((List<String>) b.get("ooid")).get(0).split("_");
            int value = a1[0].compareTo(b1[0]);
            if (value == 0) {
                return a1[1].compareTo(b1[1]);
            }
            return value;
        });
        return tag_list;
    }
}
